*******************************************************************************
* Custom Window Application
*
* (C)  Copyright Apple Computer, Inc. 1988
* All rights reserved.
*
* by Keith Rollin
* September 1, 1988
*
* This program is not much more than the standard shell that brings up three
* windows. Two of these windows are custom RoundRect windows, and the third
* one is normal window presented for comparison. This program also shows the
* use of _AlertWindow, a call new to System Disk 3.2, and the use of NULL
* events to draw the current time in the menubar.
*
* Files: System macros and equates
*        Custom.Window.inits.aii
*        RoundRect Window.aii
*
*
* Modification History:
*
* Version 1.0	kaar
*
*      September 1, 1988
*
*      First Release
*
*******************************************************************************
**********************************************************************
*                                                                    *
*             Apple IIGS Source Code Sampler, Volume I               *
*                                                                    *
*             Copyright (c) Apple Computer, Inc. 1988                *
*                       All Rights Reserved                          *
*                                                                    *
*            Written by Apple II Developer Tech Support              *
*                                                                    *
*                                                                    *
*                                                                    *
*  ----------------------------------------------------------------  *
*                                                                    *
*     This program and its derivatives are licensed only for         *
*     use on Apple computers.                                        *
*                                                                    *
*     Works based on this program must contain and                   *
*     conspicuously display this notice.                             *
*                                                                    *
*     This software is provided for your evaluation and to           *
*     assist you in developing software for the Apple IIGS           *
*     computer.                                                      *
*                                                                    *
*     DISCLAIMER OF WARRANTY                                         *
*                                                                    *
*     THE SOFTWARE IS PROVIDED "AS IS" WITHOUT                       *
*     WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,               *
*     WITH RESPECT TO ITS MERCHANTABILITY OR ITS FITNESS             *
*     FOR ANY PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO             *
*     THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH            *
*     YOU.  SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU (AND            *
*     NOT APPLE OR AN APPLE AUTHORIZED REPRESENTATIVE)               *
*     ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING,             *
*     REPAIR OR CORRECTION.                                          *
*                                                                    *
*     Apple does not warrant that the functions                      *
*     contained in the Software will meet your requirements          *
*     or that the operation of the Software will be                  *
*     uninterrupted or error free or that defects in the             *
*     Software will be corrected.                                    *
*                                                                    *
*     SOME STATES DO NOT ALLOW THE EXCLUSION                         *
*     OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION MAY              *
*     NOT APPLY TO YOU.  THIS WARRANTY GIVES YOU SPECIFIC            *
*     LEGAL RIGHTS AND YOU MAY ALSO HAVE OTHER RIGHTS                *
*     WHICH VARY FROM STATE TO STATE.                                *
*                                                                    *
*                                                                    *
**********************************************************************
	eject
	
	PRINT NOGEN,NOHDR

	STRING ASIS

	PRINT PUSH,OFF
	INCLUDE 'M16.Util'
	INCLUDE 'M16.ProDOS'
	INCLUDE 'M16.MiscTool'
	INCLUDE 'M16.QUICKDRAW'
	INCLUDE 'E16.Quickdraw'
	INCLUDE 'M16.MEMORY'
	INCLUDE 'E16.Memory'
	INCLUDE 'M16.EVENT'
	INCLUDE 'E16.EVENT'
	INCLUDE 'M16.LOCATOR'
	INCLUDE 'M16.Menu'
	INCLUDE 'M16.Control'
	INCLUDE 'M16.Window'
	INCLUDE 'E16.Window'
	INCLUDE 'M16.Dialog'
	INCLUDE 'E16.Dialog'
	INCLUDE 'M16.LineEdit'
	INCLUDE 'M16.IntMath'
	INCLUDE 'M16.Scrap'
	INCLUDE 'M16.Desk'
	INCLUDE 'M16.Texttool'
	PRINT POP

*******************************************************************************
*
*    Equates used in this program.
*
*******************************************************************************
DPHandle	equ 0	; Handle to Tool Direct Page area
DPPointer	equ DPHandle+4	; Pointer to Tool Direct Page area
deref	equ DPPointer+4	; Temporary Handle dereference area
temp1	equ deref+4	; used by DrawTime routine

ScreenMode	equ Mode640
ScreenWidth	equ 640

	EJECT
*******************************************************************************
*
*    Special macros used in this program.
*
*******************************************************************************
	MACRO 
&lab	_AlertWindow 
&lab	ldx #$590E 
	jsl $E10000 
	MEND 

	MACRO 
&lab	_StartFrameDrawing 
&lab	ldx #$5A0E 
	jsl $E10000 
	MEND 

	MACRO 
&lab	_EndFrameDrawing 
&lab	ldx #$5B0E 
	jsl $E10000 
	MEND 


	EJECT
*******************************************************************************
*
Main	PROC
*
* Description:	This is the main routine. It calls routines to Initialize
*	the tools, initialize application specific data, run the
*	main EventLoop, close the application, and close the tools.
*	Then it calls the ProDOS Quit command.
*
*
* Inputs:	NONE
*
* Outputs:	NONE
*
* External Refs:
	import InitTools
	import InitApp
	import EventLoop
	import CloseApp
	import CloseTools
	import QuitParms
*
* Entry Points:	NONE
*
*******************************************************************************

	jsr InitTools
	jsr InitApp

	_ShowCursor

	jsr EventLoop

	jsr CloseApp
	jsr CloseTools

	_Quit QuitParms

	ENDP

	EJECT
*******************************************************************************
*
Globals	Record
*
* Description:	Holder of all of our data.
*
*
* Inputs:	N/A
*
* Outputs:	N/A
*
* External Refs:
*
* Entry Points:
	export QuitParms	; used by Main
*
*******************************************************************************
*
* Standard global data
*
*******************************************************************************

TitleString	str 'Custom Window Sample'
AutString	str 'By Keith Rollin, Apple II DTS'
CopyString	str '©1988 Apple Computer'
VerString	str 'Version 1.0       September 1, 1988'
AboutData	dc.b '73/*0',13,'*1',13,'*2',13,'*3/^#0',0
SubStrings	dc.l TitleString,AutString,CopyString,VerString

MenuHeight	ds.B 2	; Stored height of menu bar
MyID	ds.B 2	; Application ID
MyDP	ds.B 2	; My direct page storage

QuitFlag	ds.W 1
QuitParms	dc.L 0	; Pathname of next app
	dc.W $00	; flags

EventRecord
EventWhat	ds.B 2
EventMessage	ds.B 4
EventWhen	ds.B 4
EventWhere	ds.B 4
EventModifiers	ds.B 2
TaskData	ds.B 4
TaskMask	dC.L $0000FFFF

	EJECT
*******************************************************************************
*
* Application specific global data
*
*******************************************************************************

; This is a list of pointers to the text that is used to create our menus. It
; is used by InitApp to find all of the menu templates and use them to create
; our menubar. This loop loads MenuPtrLen-4 into an index, gets the
; corresponding menu template pointer in this table, and uses that in a
; NewMenu call. It then decrements the index by 4, and repeats the procees
; until the index is negative.

MenuPtr	dc.l AppMenu
	dc.l FileMenu
	dc.l EditMenu
MenuPtrLen	equ *-MenuPtr


; Menu list: menu items should be numbered consecutivly starting from 250.
; As a convention, use 256 as about and 257 as Quit.

AppMenu	dc.B '$$@\N1',$0D
	dc.B '--Custom Window...\N256V',$00
	dc.B '.'
FileMenu	dc.B '$$  File  \N2',$0D
	dc.B '--Open Custom Window 1\N258',$00
	dc.B '--Open Custom Window 2\N259',$00
	dc.B '--Open Normal Window\N260',$00
	dc.B '--Close\N255V',$00
	dc.B '--Quit\N257*Qq',$00
	dc.B '.'
EditMenu	dc.B '$$  Edit  \N3',$00
	dc.B '--Undo\N250*ZzVD',$00
	dc.B '--Cut\N251*XxD',$00
	dc.B '--Copy\N252*CcD',$00
	dc.B '--Paste\N253*VvD',$00
	dc.B '--Clear\N254D',$00
	dc.B '.'

TestWindow	dc.L 0
TestWindow2	dc.L 0
NormalWindow	dc.L 0

	EndR

	EJECT
*******************************************************************************
*
InitApp	PROC
*
* Description:	Perform any application specific initialization.
*
* Inputs:	NONE
*
* Outputs:	NONE
*
* External Refs:
	import RRectDefProc
	import doUpdate
*
* Entry Points:	NONE
*
*******************************************************************************
	With Globals

	stz QuitFlag

	pha	; space for the window pointer
	pha
	PushLong #NormWindRec
	_NewWindow
	PullLong NormalWindow

	pha	; space for the window pointer
	pha
	PushLong #CustWindRec
	_NewWindow
	PullLong TestWindow

	pha	; space for the window pointer
	pha
	PushLong #CustWindRec2
	_NewWindow
	PullLong TestWindow2

	rts

WindowTitle1	str '  Custom Window #1  '
WindowTitle2	str '  Custom Window #2  '
WindowTitle3	str '  I am a Normal Window  '

myColors	dc.w $0010 ; Frame color (7-4)
	dc.w $02F0 ; Inact ttlbar(11-8), inact ttl(7-4), title (3-0)
	dc.w $0005 ; Background color (active titlebar) (3-0)

custWindRec	dc.w 0
	dc.l RRectDefProc
	dc.w 0	; FrameBits
	dc.w 40,100,160,500	; bounding rectangle
	dc.l $FFFFFFFF	; plane
	dc.l 0	; storage
	dc.l 0	; refCon
	dc.l doUpdate	; contDraw
	dc.l WindowTitle1	; window's title
	dc.l myColors	; colorTable
	dc.w $10	; vertical radius
	dc.w $20	; horizontal radius

custWindRec2	dc.w 0
	dc.l RRectDefProc
	dc.w fClose+fMove
	dc.w 60,140,140,440	; bounding rectangle
	dc.l $FFFFFFFF	; plane
	dc.l 0	; storage
	dc.l 0	; refCon
	dc.l doUpdate	; contDraw
	dc.l WindowTitle2	; window's title
	dc.l 0	; colorTable
	dc.w $10	; vertical radius
	dc.w $20	; horizontal radius

NormWindRec	DC.W WindEnd-NormWindRec
	DC.W fTitle+fClose+fMove
	DC.L WindowTitle3	; Ptr to title
	DC.L $0	; RefCon
	DC.W 0,0,0,0	; Full Size (0= default)
	DC.L 0	; Color Table Pointer
	DC.W 0,0	; Vertical/Horizontal origin
	DC.W 0,0	; Data area height,	width
	DC.W 0,0	; Max Cont height, width
	DC.W 0,0	; Pixels to scroll vert'ly, horiz'ly
	DC.W 0,0	; Pixels to page vert'ly, horiz'ly
	DC.L 0	; Information bar refcon.
	DC.W 0	; Info bar height
	DC.L 0	; DefProc.
	DC.L 0	; Routine to draw info. bar.
	DC.L doUpdate	; Routine to draw content.
	DC.W 40,40,120,590	; Size and position
	DC.L $FFFFFFFF	; Plane to put window up in (bottommost).
	DC.L 0	; Address for window record (0 to alloc)
WindEnd	equ *

	ENDP

	EJECT
*******************************************************************************
*
CloseApp	PROC
*
* Description:	Close down things. This disposes of all items and memory
*	that we allocated.
*
*
* Inputs:	NONE
*
* Outputs:	NONE
*
* External Refs:	NONE
*
* Entry Points:	NONE
*
*******************************************************************************
	With Globals

	PushLong TestWindow
	_CloseWindow

	PushLong TestWindow2
	_CloseWindow

	PushLong NormalWindow
	_CloseWindow

	rts
	ENDP

	EJECT
*******************************************************************************
*
EventLoop	PROC
*
* Description:	Main Event Loop. Handle things until user selects Quit.
*
*
* Inputs:	NONE
*
* Outputs:	NONE
*
* External Refs:
	import MenuSelect
	import ignore
	import doUpdate
	import doNullEvent
	import doClose
*
* Entry Points:	NONE
*
*******************************************************************************
	With Globals

maxEvent	equ wInactMenu

	pha	; Push on space for TaskMaster result
	PushWord #EveryEvent ; GetNextEvent mask
	PushLong #EventRecord ; Pointer to Event Record
	_TaskMaster

	pla	; Get TaskMaster result
	cmp #maxEvent+1	; do we know this event?
	blt TaskOK	; yes - so do it.
	lda #inNull	; map unknowns to null events
TaskOK	asl a	; Turn it into an index
	tax
	jsr (TaskTable,x)	; Call appropriate event handler

	lda QuitFlag	; Quit selected?
	beq EventLoop	; no - keep looping

	rts	; yes- leave the program

TaskTable	dc.W doNullEvent	; 0 Null
	dc.W Ignore	; 1 MouseDown
	dc.W Ignore	; 2 MouseUp
	dc.W Ignore	; 3 KeyDown
	dc.W Ignore	; 4 undefined
	dc.W Ignore	; 5 AutoKey
	dc.W Ignore	; 6 Update
	dc.W Ignore	; 7 undefined
	dc.W Ignore	; 8 Activate
	dc.W Ignore	; 9 Switch
	dc.W Ignore	; 10 Desk accessory
	dc.W Ignore	; 11 Device driver
	dc.W Ignore	; 12 ap
	dc.W Ignore	; 13 ap
	dc.W Ignore	; 14 ap
	dc.W Ignore	; 15 ap
	dc.W Ignore	; TASK 0 indesk
	dc.W MenuSelect	; TASK 1 in menuBar
	dc.W Ignore	; TASK 2 in system window
	dc.W Ignore	; TASK 3 in content
	dc.W Ignore	; TASK 4 in Drag
	dc.W Ignore	; TASK 5 in grow
	dc.W doClose	; TASK 6 in goaway
	dc.W Ignore	; TASK 7 in zoom
	dc.W Ignore	; TASK 8 in info bar
	dc.W MenuSelect	; TASK 9 in special	menu
	dc.W Ignore	; TASK 10 in NDA
	dc.W Ignore	; TASK 11 in frame
	dc.W Ignore	; TASK 12 in drop

	ENDP

	EJECT
*******************************************************************************
*
MenuSelect	PROC
*
* Description:	This routine is called when TaskMaster returns a menu
*	event. It takes the menu item that was hit and calculates
*	an offset into the menu dispatch table. It then calls that
*	routine and unhilites the menu when it is done.
*
* Inputs:	TaskData holds menu item selected.
*
* Outputs:	NONE
*
* External Refs:
	import ignore
	import doAbout
	import doQuit
	import doOpen1
	import doOpen2
	import doOpen3
	import doClose
*
* Entry Points:	NONE
*
*******************************************************************************
	With Globals

	lda TaskData	; Get the ID of the menu item selected.
	sec	; Turn it into an index by subtracting
	sbc #250	; the starting ID number (250) and mul-
	asl a	; tiplying by 2 (each table entry con-
	tax	; sists of 2 bytes).
	jsr (menuTable,x)	; Call the routine behind it.

	PushWord #0	; Routine done - unhilite the menubar.
	PushWord taskData+2
	_HiLiteMenu

	rts

MenuTable	dc.W Ignore	; undo
	dc.W Ignore	; cut
	dc.W Ignore	; copy
	dc.W Ignore	; paste
	dc.W Ignore	; clear
	dc.W DoClose	; close
	dc.W DoAbout	; about this program
	dc.W DoQuit	; quit selected
	dc.W DoOpen1	; open a custom window
	dc.W DoOpen2	; open another custom window
	dc.W DoOpen3	; open a normal window
	ENDP

	EJECT
*******************************************************************************
*
Ignore	PROC
*
* Description:	Called when I want to ignore an event.
*
*
* Inputs:	NONE
*
* Outputs:	NONE
*
* External Refs:	NONE
*
* Entry Points:	NONE
*
*******************************************************************************

	rts
	ENDP

	EJECT
*******************************************************************************
*
DoNullEvent	Proc
*
* Description:	Performs tasks when there is nothing else to do...In this
*	case, draw the time in the menubar.
*
*
* Inputs:	NONE
*
* Outputs:	NONE
*
* External Refs:	NONE
*
* Entry Points:	NONE
*
*******************************************************************************
	With Globals

	pha	; get the time
	pha
	pha
	pha
	_ReadTimeHex

	lda 1,s	; compare to see if 1 second
	cmp oldTime	; has passed...
	bne DrawTime

	lda 3,s
	cmp oldTime+2
	bne DrawTime

	lda 5,s
	cmp oldTime+4
	bne DrawTime

	lda 7,s
	cmp oldTime+6
	bne DrawTime
	brl ExitNull	; no it hasn't...do nothing

DrawTime		; time has passed, draw it.
	pha	; save the old port
	pha
	_GetPort
	PullLong oldPort

	pha	; switch to the menu manager port
	pha
	_GetMenuMgrPort
	lda 1,s	; save this for metrics later
	sta temp1
	lda 3,s
	sta temp1+2
	_SetPort

	PushLong #TimeString ; get the time as a string
	_ReadAsciiTime

	ldx #18	; strip off the high bits
loop	lda TimeString,x
	and #$7F7F
	sta TimeString,x
	dex
	dex
	bpl Loop

	pha	; get the length of the time string
	PushLong #TimeString
	_CStringWidth

; put it on the screen so that its right edge is 10 pixels from
; the right edge of the screen. It is always positioned 10 pixels
; down from the top of the screen.

	ldy #oportRect+6
	lda [temp1],y
	sec
	sbc 1,s	; subtract the width on the stack
	sbc #10	; plus some...
	sta 1,s	; push on the X-Coord
	ldy #oportRect
	lda [temp1],y
	clc
	adc #10	; push on the Y-coord
	pha
	_MoveTo

; Save and set the text mode to modeCopy
	pha
	_GetTextMode

	PushWord #0
	_SetTextMode

; Finally draw the string

	PushLong #TimeString
	_DrawCString

; Reset the text mode and the GrafPort

	_SetTextMode

	PushLong oldPort
	_SetPort

ExitNull
	PullLong oldTime
	PullLong oldTime+4

	rts

oldTime	dc.b 0,0,0,0,0,0,0,0
oldPort	ds.b 4

TimeString	DS.B 20
	DC.B 0

	ENDP

	EJECT
*******************************************************************************
*
doUpdate	PROC
*
* Description:	Called by TaskMaster to perform updates. This routine
*	does nothing, as we have nothing to update with!
*
*
* Inputs:	NONE
*
* Outputs:	NONE
*
* External Refs:	NONE
*
* Entry Points:	NONE
*
*******************************************************************************
	with Globals

	rtl
	ENDP

	EJECT
*******************************************************************************
*
doQuit	PROC
*
* Description:	Quit routine. Set the QuitFlag to TRUE for the EventLoop.
*
*
* Inputs:	NONE
*
* Outputs:	QuitFlag set to $FFFF
*
* External Refs:	NONE
*
* Entry Points:	NONE
*
*******************************************************************************
	With Globals

	lda #$FFFF
	sta QuitFlag
	rts
	ENDP


	EJECT
*******************************************************************************
*
doAbout	PROC
*
* Description:	Bring up an AlertWindow box with our name in it. This call
*	was added on System Disk 3.2.
*
* Inputs:	NONE
*
* Outputs:	NONE
*
* External Refs:	NONE
*
* Entry Points:	NONE
*
*******************************************************************************
	With Globals

	pha	; space for result
	PushWord #1	; we are using P-Strings
	PushLong #SubStrings
	PushLong #AboutData
	_AlertWindow	; new macro defined above
	pla	; pull off button hit

	rts

	ENDP

	EJECT
*******************************************************************************
*
doOpen	proc
*
* Description:	Opens a window by making it visible.
*
*
* Inputs:	NONE
*
* Outputs:	NONE
*
* External Refs:	NONE
*
* Entry Points:
	entry doOpen1
	entry doOpen2
	entry doOpen3
*
*******************************************************************************
	with Globals
	
doOpen1	lda TestWindow
	ldx TestWindow+2
	bra CommonOpen

doOpen2	lda TestWindow2
	ldx TestWindow2+2
	bra CommonOpen

doOpen3	lda NormalWindow
	ldx NormalWindow+2

CommonOpen
	phx	; push the window ptr on for ShowWind
	pha
	phx	; and push a set on for Select
	pha
	_SelectWindow	; bring it to front
	_ShowWindow	; and show it.

	rts

	ENDP


	EJECT
*******************************************************************************
*
doClose	proc
*
* Description:	Closes a window by making it invisible.
*
*
* Inputs:	NONE
*
* Outputs:	NONE
*
* External Refs:	NONE
*
* Entry Points:	NONE
*
*******************************************************************************
	with globals

	pha	; get the front window
	pha
	_FrontWindow
	_HideWindow	; and hide it

	rts
	ENDP

	Include 'Custom.Window.inits.aii'
	Include 'RoundRect Window.aii'

	END

